Skip to content

fix(clients): example paths no longer open missing files - #30021

Closed
BilalIrfanContact wants to merge 4 commits into
pingdotgg:mainfrom
BilalIrfanContact:fix/issue-29421
Closed

BilalIrfanContact wants to merge 4 commits into
pingdotgg:mainfrom
BilalIrfanContact:fix/issue-29421

Conversation

@BilalIrfanContact

Copy link
Copy Markdown
Contributor

Problem

An example such as avatars/u1.webp becomes a file chip labelled u1.webp even when no such workspace file exists. The reply loses part of its text, and clicking the chip opens an error panel.

Fixes #29421.

Change

Keep inline paths as plain code until the thread's environment confirms they exist. Existing files remain clickable and show the path exactly as written, including line/column suffixes. The shared lookup reuses batched metadata and cached workspace search; unreadable, disconnected, and pending lookups stay plain code. Explicit Markdown links keep their existing behavior.

This covers web/desktop, native mobile rendering, and find-in-thread text. Native link labels are escaped independently so Markdown characters in names such as ./src/__tests__/main.ts remain literal.

Scope and approval

Submitted under the focused obvious-bug exception: the change addresses the report's nonexistent-file links and loss of authored text. The shared lookup and client changes support that one problem. No separate maintainer approval has been received.

Related: #29657 implements the label-only alternative and explicitly leaves nonexistent paths clickable. This PR also prevents those links.

Verification

  • vp run check:changed upstream/main --concurrency 2 passed on the rebased branch: formatting, lint, both Knip passes, 34 affected-package typechecks, 90 tests across 8 files (including browser tests), and 14 focused React compiler checks.
  • Extended the existing native label test with Markdown metacharacters. It failed before the escaping correction and passed in the run above.
  • Reused the same saved assistant-message fixture and workspace in an isolated real dev client on Linux (Node 24.22.1, Electron/Chromium, light appearance, 1280×800). Before: missing path was a basename-only link and opened an image error. After: it is plain code; clicking opens no panel. The existing src/existing.ts shows its full label and opens its actual source. This is a deterministic rendering fixture, not a paid provider turn.

Before

Before: the example loses its directory and becomes a file link

After

After: the missing path stays plain code and the existing file retains its full label

Additional captures: before clicking the missing-file link · after opening the existing file.

Native-device runtime was unavailable because Agent device access is disabled; mobile unit tests and typechecking were run. Packaged desktop and remote/relay connections were not exercised. Mobile may retain stale metadata for about 60 seconds; an inline path sharing an authored link's URL stays plain code to avoid changing that link's label.

Implemented with Claude Opus 5.5 (medium, Claude Code in T3 Code); verification and follow-up fixes with GPT-6.1 Sol (Codex in T3 Code).

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Nov 3, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at bbf6d85

Macroscope's review found this PR approvable — Inline paths remain code unless the file is confirmed to exist, and existing-file chips preserve the written path. The added checks use permission-gated, cached read operations and reject network paths, with no persistent-data changes.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The PR adds workspace-existence checks for inline-code file paths in mobile and web Markdown rendering. Existing paths can render as file links while non-existing paths remain inline code. Mobile Markdown conversion reports inline-file URLs, and text search retains the written inline-code path.

Changes: Inline-Code File Path Rendering

Layer / File(s) Summary
Workspace file existence lookup
packages/client-runtime/src/state/workspaceFileExistence.ts, packages/client-runtime/src/state/workspaceFileExistence.test.ts, packages/client-runtime/src/state/projectCommands.ts
A new atom checks candidate paths against file metadata and workspace search results. Project environment atoms expose the lookup and search family.
Existence-aware Markdown conversion
apps/mobile/src/lib/markdownDocument.ts, apps/mobile/src/lib/markdownInlineFileLinks.test.ts, apps/mobile/src/lib/markdownHtml.test.ts
Markdown conversion accepts an existence callback and returns converted Markdown with inline-file URLs. Tests cover existing and missing paths, authored links, fenced code, and path text.
Mobile inline-file rendering
apps/mobile/src/native/SelectableMarkdownText.types.ts, apps/mobile/src/native/SelectableMarkdownText.tsx, apps/mobile/src/native/useExistingInlineFiles.ts, apps/mobile/src/native/EnrichedMarkdownText.tsx, apps/mobile/src/native/useEnrichedLinkVariants.ts, apps/mobile/src/features/files/FileMarkdownPreview.tsx, apps/mobile/src/features/threads/ThreadFeed.tsx
Mobile components pass workspace scope to the existence lookup. Inline-code file links use the written path as their label.
Web inline-file rendering
apps/web/src/components/ChatMarkdown.tsx
The web renderer checks inline-code candidates against workspace files and renders a file chip only for candidates found to exist. The chip uses the written code text as its label.
Inline-code text in search results
packages/shared/src/threadFindText.ts, packages/shared/src/threadFindText.test.ts
Searchable text for resolved inline-code file targets uses the trimmed written path. Tests cover paths in assistant and user messages.

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix · Severity of issue fixed: Low

Possibly related issues

  • Issue 28509 concerns authored text being replaced by resolved file labels in mobile Markdown. This PR changes inline-code file-link labels, but does not clearly address the authored-text case for other links.
  • Issue 22181 concerns inline code with a line suffix being rendered as a file chip. The new existence check leaves paths that do not exist as inline code; handling of position suffixes is not established in the provided context.
  • Issue 10553 concerns relative file references from another checkout. The new check applies to inline-code paths in the thread workspace, but the issue’s Markdown-link and click-time resolution cases are not addressed.

Suggested reviewers: juliusmarminge, maria-rcks

Merge Risk: Minimal · up to bbf6d

The identified file-opening concern does not block merging; the link opens the file found in the workspace.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title "fix(clients): example paths no longer open missing files" names the main change: inline-code paths that do not exist stop rendering as file chips. The changeset adds existence checks for in…
Description check Passed The description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section explains the bug with an example, expected behavior, and a linked issue…
Linked Issues check Passed Directly linked issue #29421 requires that a nonexistent path in inline code not become a file chip that drops its directory text and opens a missing-file preview. The minimum outcome is plain inline …
Out of Scope Changes check Passed The issue scope names apps/web. The change also touches shared and native code: apps/mobile inline-file rendering (markdownDocument.ts, useEnrichedLinkVariants.ts, useExistingInlineFiles.ts,…
Full details: Title check

Explanation

The title "fix(clients): example paths no longer open missing files" names the main change: inline-code paths that do not exist stop rendering as file chips. The changeset adds existence checks for inline file paths across web, mobile, and shared text code, which matches the title's core fix. The title uses the conventional commit format and is specific. It does not name the existence-check mechanism, but it does not need to cover every detail.

Full details: Description check

Explanation

The description follows the template. It has Problem, Change, Scope and approval, and Verification sections. The Problem section explains the bug with an example, expected behavior, and a linked issue. The Change section explains the fix and why it covers web, native mobile, and find-in-thread text. The Scope section invokes the focused obvious-bug exception and explains why it applies, and it notes that no maintainer approval was received. The Verification section lists the checks run, observed before and after results, and what could not be checked, including native-device runtime. The description also includes the model and harness, as the template asks.

Full details: Linked Issues check

Explanation

Directly linked issue #29421 requires that a nonexistent path in inline code not become a file chip that drops its directory text and opens a missing-file preview. The minimum outcome is plain inline code with full text. The reviewed head implements this:

  • Web (apps/web/src/components/ChatMarkdown.tsx): per the change summary, inline-code candidates are checked against workspace files, and a chip is rendered only when the check finds the file. fileLinkChip accepts a label override. The head read confirms the existence-gated rendering path and the resolveWorkspaceFilePath and inlineCodeFilePathCandidate imports. The read was truncated, so the inline-code branch was not read line by line.
  • Shared existence lookup (packages/client-runtime/src/state/workspaceFileExistence.ts, read at head): a candidate counts as existing only when its metadata entry is non-null, or when a basename or stripped workspace search finds a match. Metadata errors, search errors, pending results, and disconnected lookups count as missing. For the issue example avatars/u1.webp, the lookup contains a slash and is not a basename, so no search runs and the path stays missing.
  • Tests: workspaceFileExistence.test.ts covers existing, missing, pending, null-metadata, and UNC cases. markdownInlineFileLinks.test.ts and threadFindText.test.ts cover the mobile and find-text paths.
  • Existing files stay clickable. The chip label keeps the path as written, which satisfies the issue's second option.

The author reports a browser check on a saved fixture. The web gate has no dedicated unit test in the change summary. The issue does not require one, so this does not change the verdict.

Full details: Out of Scope Changes check

Explanation

The issue scope names apps/web. The change also touches shared and native code: apps/mobile inline-file rendering (markdownDocument.ts, useEnrichedLinkVariants.ts, useExistingInlineFiles.ts, EnrichedMarkdownText.tsx, SelectableMarkdownText types), packages/client-runtime (workspaceFileExistence.ts, projectCommands.ts), and packages/shared/src/threadFindText.ts.

These changes connect to the reported behavior:

  • The same inline-code file-chip behavior exists on native rendering and in find-in-thread text. The threadFindText change makes searchable text match the code text shown for inline paths.
  • The mobile escaping applies to labels of rewritten inline-file links only.
  • The client-runtime lookup is the shared existence check that the web and mobile gates use.

No change was shown to be unrelated to the inline-path chip behavior. The shared classifier inlineCodeFilePathCandidate is not modified; the fix gates its output by existence. The author's note that no separate maintainer approval was received is a process matter. It does not show unrelated code.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between cefb544 and bbf6d85.

Files selected for processing: 16
  • apps/mobile/src/features/files/FileMarkdownPreview.tsx
  • apps/mobile/src/features/threads/ThreadFeed.tsx
  • apps/mobile/src/lib/markdownDocument.ts
  • apps/mobile/src/lib/markdownHtml.test.ts
  • apps/mobile/src/lib/markdownInlineFileLinks.test.ts
  • apps/mobile/src/native/EnrichedMarkdownText.tsx
  • apps/mobile/src/native/SelectableMarkdownText.tsx
  • apps/mobile/src/native/SelectableMarkdownText.types.ts
  • apps/mobile/src/native/useEnrichedLinkVariants.ts
  • apps/mobile/src/native/useExistingInlineFiles.ts
  • apps/web/src/components/ChatMarkdown.tsx
  • packages/client-runtime/src/state/projectCommands.ts
  • packages/client-runtime/src/state/workspaceFileExistence.test.ts
  • packages/client-runtime/src/state/workspaceFileExistence.ts
  • packages/shared/src/threadFindText.test.ts
  • packages/shared/src/threadFindText.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

@maria-rcks

maria-rcks commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

Verified unchanged head bbf6d850401c80adf312bec5fd5546417089e7e9 on Linux with the real dev web client, repository Playwright, /usr/bin/google-chrome, and Codex gpt-6.1-sol through the local proxy. No mocks, saved-message fixtures, or demo provider were used.

Created a local git project and thread through the app. A real Codex turn created and committed the source files. On github/main (cefb544af3c9), its reply rendered nonexistent avatars/u1.webp as a basename-only link; clicking it opened "Unable to load workspace image."

Stopped main before starting the PR, copied only the app-created development state for matching data, and repeated the flow. A fresh Codex turn on the PR also read the real files and produced the reply.

  • Missing avatars/u1.webp and missing/example.ts retain their full text as code. Clicking the missing image path opens no panel.
  • src/existing.ts:2:1 retains its written label and opens the actual source with line 2 highlighted.
  • ./src/__tests__/main.ts keeps its underscores and opens the correct source.
  • The explicit Markdown file link still opens the source. npm run dev remains code.
  • Find-in-thread finds the complete avatars/u1.webp text and advances between matches.

vp i completed in both checkouts. Blacksmith ran vp test run packages/client-runtime/src/state/workspaceFileExistence.test.ts packages/shared/src/threadFindText.test.ts apps/mobile/src/lib/markdownInlineFileLinks.test.ts apps/mobile/src/lib/markdownHtml.test.ts: 4 files, 66 tests passed. Existing GitHub CI checks passed on this head. No source changes or push were needed.

Before on main: missing paths become basename-only links

After on the PR: the same reply keeps missing paths as code and full existing-file labels

PR interaction recording: missing path, source navigation, explicit link, and full-path search

Not verified

Native iOS/Android and packaged desktop clients were not exercised on this Linux VM. Mobile Markdown and shared lookup tests passed, but they do not prove native rendering. Remote/relay/tunnel connections, Windows paths, disconnected or restricted-permission sessions, cache expiry, and providers other than Codex were not exercised.

@chrismin13

Copy link
Copy Markdown

this works amazingly well, fixes a long standing bug in t3code and should be merged imo :D

Copy link
Copy Markdown
Member

Thanks for the thoughtful fix and verification, Bilal. #29657 by voltcrash addresses the same reported issue by preserving the authored path, and is actively maintained against current main. This branch has had no author update for over a week and main has changed the affected files, so I’m closing it as the duplicate. The other approach still leaves missing paths clickable; if preventing that remains important, please feel free to propose a smaller PR focused on that behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Inline code like avatars/u1.webp becomes a file chip labeled u1.webp even when the path does not exist

4 participants